/*
 * RenderDevice.h
 *
 *  Created on: 2009/01/05
 *      Author: Yongshik Cho
 */

#ifndef RENDERDEVICE_H_
#define RENDERDEVICE_H_

#include "core/ISingleton.h"
#include "Texture.h"
#include "Viewport.h"
#include "active/Renderable.h"
#include "core/Color.h"
#include "Camera.h"
#include "Quadtree.h"
#include "core/Polygon2D.h"
#include "Path.h"
#include "ShapeObject.h"
#include "ParticleObject.h"
#include "RibbonObject.h"
#include "TextObject.h"
#include "device/DeviceSettings.h"
#include "sqplus/sqplus.h"
using namespace SqPlus;


class RenderDevice : public ISingleton<RenderDevice>
{
public:
	static const Vector2D _DEFAULT_AXIS_DIRECTION;

	static const uint32 MATRIX_MODELVIEW	= 0x1700;
	static const uint32 MATRIX_PROJECTION	= 0x1701;
	static const uint32 MATRIX_TEXTURE		= 0x1702;
	static const uint32 MATRIX_COLOR		= 0x1800;

public:
	RenderDevice(Rect2D rect = Rect2D(0.f, 0.f), DeviceSettings* sets = 0);
	virtual ~RenderDevice();

public:
	const Viewport& getViewport() const { return mViewport; }
	void setViewport(const Viewport& vp);
	void buildQuadtree(const Rect2D& rect);

	Quadtree* getQuadtree() { return mQuadtree; }

	const float getWidth() const { return mViewport.getWidth(); }
	const float getHeight() const { return mViewport.getHeight(); }

	virtual const Vector3D fixCoordSystem(const Vector3D v) { return v; }
	virtual const Quaternion fixCoordSystemQuat(const Quaternion q) { return q; }

	virtual void scaleTexture(const uint32 width, const uint32 height, const uint32 rowBytes, const uint32 format, const uint8* bitmap,
				const uint32 scalew, const uint32 scaleh, uint8* dest) {}

	virtual Texture* createTexture(const String& p, const uint32 width, const uint32 height,
			const uint32 orgWidth, const uint32 orgHeight, const uint32 rowBytes, const uint32 format, uint8* bitmap, uint8* orgBitmap) { return 0; }
	virtual void rebindTexture(Texture* tex, const uint32 format, uint8* bitmap) {}

	virtual void disposeTexture(Texture* texture) {};
	virtual void cleanupTextures() {}

	virtual void setPerspective(const float aspect, const float fov, const float nearClip, const float farClip) {}
	virtual void lookAt(const Vector3D& eye, const Vector3D& target, const Vector3D& up) {}
	virtual void setOrthogonal(const Camera* camera) {}

	virtual void clear(const Color& color) {}
	virtual void render(Renderable* r) {}
	virtual void drawQuadratic(const Rect2D& viewRect, Renderable* r) {}
	virtual void drawShape(ShapeObject* shape) {}
	virtual void drawParticle(ParticleObject* particle) {}
	virtual void drawRibbon(RibbonObject* ribbon) {}
	virtual void drawText(TextObject* text) {}
	virtual void drawCenter() {}
	virtual void drawRect(const Rect2D& r, const Color& color) {}
	virtual void drawLine(const Line2D& l, const Color& color) {}
	virtual void drawFillRect(const Rect2D& r, const Color& fillColor) {}
	virtual void drawPolygon(Polygon2D& poly, const Color& color) {}
	virtual void drawFillPolygon(Polygon2D& poly, const Color& fillColor) {}
	virtual void drawBezier(Curve2D& curve, const Color& color, uint32 stepCount = Curve2D::_DEFAULT_STEP_COUNT) {}
	virtual void drawFillBezier(Curve2D& curve, const Color& fillColor, uint32 stepCount = Curve2D::_DEFAULT_STEP_COUNT) {}
	virtual void drawPath(Path& path, const Color& color, uint32 stepCount = Curve2D::_DEFAULT_STEP_COUNT) {}
	virtual void drawPixels(const uint32 width, const uint32 height, const uint32 format, const uint8* ucbuf) {}
	virtual void drawCircle(const Rect2D& r, const Color& color) {}
	virtual void drawFillCircle(const Rect2D& r, const Color& fillColor) {}

	virtual const Vector2D getScaled(const Vector2D& value) { return value; }
	virtual const Vector2D getDevicePosition(const Vector2D& p) { return p; }
	virtual const Rect2D getDeviceRect(const Rect2D& r) { return r; }
	virtual const float getViewAspect() const { return 1.f; }

	virtual void translate(const Vector2D& t) {}
	virtual void setMatrixMode(const uint32 mode) {}
	virtual void pushMatrix() {}
	virtual void popMatrix() {}

	virtual void swapBuffers() {}

	const uint8 getFirstBiggerBitIndex(const uint32 bits)
	{
		uint32 shift = 0x1;
		uint32 new_value = 0;
		for(uint8 i=0;i<32;i++)
		{
			new_value = shift << i;
			if(new_value >= bits)
				return i;
		}

		return 0;
	}

	inline virtual const int32 getSupportedTextureSize() const { return mSupportedTextureSize; }
	inline virtual const uint8 getBitsPerPixel() const { return mBitsPerPixel; }
	inline virtual const uint8 getBitsDepth() const { return mBitsDepth; }
	inline virtual const uint8 getBitsStencil() const { return mBitsStencil; }
	inline virtual const uint8 getAlphaBuffer() const { return mAlphaBuffer; }
	inline virtual const uint8 getBufferCount() const { return mBufferCount; }

public:
	virtual void onSize(const uint8 type, const Vector2D& size) {}

public:
	static RenderDevice& GetInstance()
	{
		assert(m_pInstance);
		return *m_pInstance;
	}
	static RenderDevice* GetInstancePtr()
	{
		return m_pInstance;
	}

protected:
	Viewport				mViewport;
	Quadtree*				mQuadtree;
	DeviceSettings*			mSettings;

	int32					mSupportedTextureSize;
	uint8					mBitsPerPixel;
	uint8					mBitsDepth;
	uint8					mBitsStencil;
	uint8					mAlphaBuffer;
	uint8					mBufferCount;
};

//must be declared here
DECLARE_INSTANCE_TYPE(RenderDevice)

#endif /* RENDERDEVICE_H_ */
